#include <iostream>
#include <vector>

// ------ Observable ------
class Observer;
class Observable {
public:
    void register_(Observer* x);
    void unregister(Observer* x);
    void notifyAll();
private:
    std::vector<Observer*> _observers;
};

// ------ Observer ------
class Observer {
public:
    Observer(): _subject(NULL) {}
    virtual ~Observer() {
        // 此处析构也不是原子的，如果析构一半怎么办？
        if (_subject)
            // _subject 真的还在吗？
            std::cout << "unregister" << std::endl;
            _subject->unregister(this);
    }
    virtual void update() = 0;
    void observe(Observable *s) {
        s->register_(this);
        _subject = s;
    }
private:
    Observable* _subject;
};

void Observable::register_(Observer* x) {
    _observers.push_back(x);
}

void Observable::unregister(Observer* x) {
    std::vector<Observer*>::iterator it = _observers.begin();
    for (; it != _observers.end(); ++it) {
        if (*it == x) {
            _observers.erase(it);
            break;
        }
    }
}

void Observable::notifyAll() {
    for (Observer* x : _observers) {
        // 危险，x 真的还在吗？
        x->update();
    }
}

// ------ Foo ------
class Foo: public Observer {
public:
    Foo(const char* name): _name(name) {}
    ~Foo() {};
    void update() {
        std::cout << _name << " is notified" << std::endl;
    }
private:
    std::string _name;
};

// ------ main ------
int main() {
    Observable *observable = new Observable();
    Foo *f1 = new Foo("allen");
    Foo *f2 = new Foo("luffy");
    Foo *f3 = new Foo("zoro");
    Foo *f4 = new Foo("sanji");

    f1->observe(observable);
    f2->observe(observable);
    f3->observe(observable);
    f3->observe(observable);

    delete observable;
    // 再 delete，出现 segment fault 都是幸运的了
    delete f1;
    delete f2;
    delete f3;
    delete f4;

    //observable->notifyAll();
}
